﻿
    using System;
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Media.Imaging;
namespace YoucaiReader.Helper.Drawing
{
    public sealed class FontInfo
    {
        private Style defaultStyle;
        private Dictionary<string, FontCharacters> fontLookup = new Dictionary<string, FontCharacters>();
        private TextBlock tester = new TextBlock();

        public FontInfo(FontSource fontSource)
        {
            if (fontSource != null)
            {
                this.tester.FontSource = (fontSource);
            }
            this.defaultStyle = new Style(this.tester.GetType());
        }

        internal StringMeasurements GetMeasurements(FontImpl font, string value)
        {
            FontCharacters characters;
            if ((value == null) || (font == null))
            {
                throw new ArgumentNullException();
            }
            if (!this.fontLookup.TryGetValue(font.getKey(), out characters))
            {
                characters = new FontCharacters(font.getStyle(), this);
                this.fontLookup.Add(font.getKey(), characters);
            }
            float[] widths = new float[value.Length];
            float lineWidth = 0f;
            float num2 = 0f;
            float width = 0f;
            int num4 = 0;
            for (int i = 0; i < value.Length; i++)
            {
                char glyph = value[i];
                float num6 = characters.GetWidth(glyph);
                widths[i] = num6;
                lineWidth += num6;
                num2 += num6;
                if (IsNewLineChar(glyph) && ((i == 0) || !IsNewLineChar(value[i - 1])))
                {
                    num4++;
                    if (num2 > width)
                    {
                        width = num2;
                    }
                    num2 = 0f;
                }
            }
            if (num2 > width)
            {
                width = num2;
            }
            return new StringMeasurements(width, characters.Height * (num4 + 1), lineWidth, characters.Height, characters.Descent, characters.Ascent, widths);
        }

        private static bool IsNewLineChar(char glyph)
        {
            if (glyph != '\n')
            {
                return (glyph == '\r');
            }
            return true;
        }

        private class FontCharacters
        {
            private FontInfo parent;
            private Style style;
            private Dictionary<char, float> widths = new Dictionary<char, float>();

            public FontCharacters(Style style, FontInfo parent)
            {
                this.style = style;
                this.parent = parent;
                this.Height = -1f;
            }

            public float GetWidth(char glyph)
            {
                float num;
                if (!this.widths.TryGetValue(glyph, out num))
                {
                    if (!FontInfo.IsNewLineChar(glyph))
                    {
                        if (this.parent.tester.Style != this.style)
                        {
                            this.parent.tester.Style=(this.style);
                        }
                        this.parent.tester.Text=(glyph.ToString());
                        num = (float) this.parent.tester.ActualWidth;
                        if (this.Height < 0f)
                        {
                            this.Height = (float) this.parent.tester.ActualHeight;
                            this.parent.tester.Text=("M");
                            WriteableBitmap bitmap = new WriteableBitmap(this.parent.tester, null);
                            this.Descent = this.Height - bitmap.PixelHeight;
                            this.Ascent = ((float) this.parent.tester.FontSize) - this.Descent;
                            for (int i = 0; i < bitmap.PixelHeight; i++)
                            {
                                int index = i * bitmap.PixelWidth;
                                int num4 = (i + 1) * bitmap.PixelWidth;
                                bool flag = false;
                                while ((index < num4) && !flag)
                                {
                                    if (bitmap.Pixels[index] != 0)
                                    {
                                        flag = true;
                                    }
                                    index++;
                                }
                                if (flag)
                                {
                                    this.Ascent = bitmap.PixelHeight - i;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        num = 0f;
                    }
                    this.widths[glyph] = num;
                }
                return num;
            }

            public float Ascent { get; set; }

            public float Descent { get; set; }

            public float Height { get; set; }
        }
    }
}

